﻿// Jinx AJAX Framework
// Copyright (C) 2008 Blake Hegerle
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.IO;
using System.Net;
using Jinx.Applications;
using Jinx.Communications;
using Core.Json;

namespace TestFramework
{
    public class ContextualClient
    {
        private readonly string Url;
        private Token token;
        private Cookie TokenCookie;

        public ContextualClient(string VDir)
        {
            Url = string.Format("http://localhost/{0}/", VDir);

            var AppCreationUrl = Url + Constants.VirtualDirectories.APPLICATION_CREATION_SERVER;

            GetToken(AppCreationUrl);
        }

        public Token Token
        {
            get { return token; }
        }

        public void Call(string ControllerPath, string Method, object Argument)
        {
            var MethodUrl = string.Format("{0}{1}/{2}/{3}.action?{4}={5}",
                                          Url,
                                          Constants.VirtualDirectories.ACTION_SERVER,
                                          ControllerPath,
                                          Method,
                                          Constants.ACTION_SERVER_QUERY_STRING_ARGUMENT_NAME,
                                          Argument.ToJson());

            var Request = NewRequest(MethodUrl);

            Request.CookieContainer = new CookieContainer();
            Request.CookieContainer.Add(TokenCookie);

            WebResponse Response = null;
            try
            {
                try
                {
                    Response = Request.GetResponse();
                }
                catch (WebException e)
                {
                    Response = e.Response;
                }

                CheckResponse(Response.GetResponseStream());
            }
            finally
            {
                if (Response != null)
                    Response.Close();
            }
        }

        private static void CheckResponse(Stream Stream)
        {
            using (var Reader = new StreamReader(Stream))
            {
                var ResponseObject = Reader.JsonToObject<ResponseObject>();

                if (ResponseObject.Success == false)
                    throw new Exception("Call failed: " + ResponseObject.ExceptionSummary.Message);
            }
        }

        private void GetToken(string AppCreationUrl)
        {
            var Request = NewRequest(AppCreationUrl);
            Request.CookieContainer = new CookieContainer();

            using (var Response = (HttpWebResponse)Request.GetResponse())
            {
                TokenCookie = Response.Cookies[Constants.Cookies.APPLICATION_TOKEN_COOKIE];

                var TokenJson = Uri.UnescapeDataString(TokenCookie.Value);
                token = TokenJson.JsonToObject<Token>();
            }
        }

        private static HttpWebRequest NewRequest(string Url)
        {
            return (HttpWebRequest)WebRequest.Create(Url);
        }
    }
}